﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace Our.Umbraco.uDbCompare
{
    public partial class HiddenTabs : System.Web.UI.UserControl
    {
        public bool UseRemoteConnectionString { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
                BindData();
        }

        public void BindData()
        {
            if (SessionVars.IsValidDbConnection(UseRemoteConnectionString))
            {
                ShowTabsButton.Enabled = true;
            }
            else
            {
                ShowTabsButton.Enabled = false;
            }
        }

        protected void ShowTabsButton_OnClick(object sender, EventArgs e)
        {
            string tabQuery = @"select ct.nodeid, ct.alias, t.text, ct.masterContentType, n.nodeObjectType
                                from cmsContentType ct join cmsTab t on ct.nodeId = t.contenttypeNodeId
                                join umbracoNode n on ct.nodeId = n.id
                                            ";

            DataTable tabTable = Db.QueryDb(tabQuery, UseRemoteConnectionString);
            
            var duplicateTabTable = tabTable.Clone();
            duplicateTabTable.Clear();

            List<Guid> nodeObjectTypes = new List<Guid>();
            foreach (DataRow row in tabTable.Rows)
            {
                Guid nodeObjectType = (Guid)row["nodeObjectType"];
                if (!nodeObjectTypes.Contains(nodeObjectType))
                {
                    nodeObjectTypes.Add(nodeObjectType);
                }
            }

            // Each nodeObjectType is a different area
            foreach (var nodeObjectType in nodeObjectTypes)
            {
                // Get all the child parent mappings
                var childParentMapping = new Dictionary<int, int>();
                var tabNames = new Dictionary<int, List<string>>();
                var docTypeAlias = new Dictionary<int, string>();

                foreach (DataRow row in tabTable.Rows)
                {
                    int nodeId = (int)row["nodeid"];
                    string alias = row["alias"] as string;
                    string tabName = row["text"] as string;
                    int? parentId = row["masterContentType"] as int?;
                    Guid currentNodeObjectType = (Guid)row["nodeObjectType"];


                    if (nodeObjectType == currentNodeObjectType)
                    {
                        if (!childParentMapping.ContainsKey(nodeId))
                        {
                            // parentId can be null or 0 - standarize on 0
                            if (parentId == null)
                            {
                                parentId = 0;
                            }

                            childParentMapping.Add(nodeId, parentId.Value);
                        }

                        if (!docTypeAlias.ContainsKey(nodeId))
                        {
                            docTypeAlias.Add(nodeId, alias);
                        }

                        if (!tabNames.ContainsKey(nodeId))
                        {
                            var tabNameList = new List<string>();
                            tabNameList.Add(tabName);
                            tabNames.Add(nodeId, tabNameList);
                        }
                        else
                        {
                            tabNames[nodeId].Add(tabName);
                        }
                    }
                }

                

                // Loop through all the nodes
                foreach (var nodeId in childParentMapping.Keys)
                {
                    // No point in checking unless there are tab names & a parent for the node
                    if (tabNames.ContainsKey(nodeId) && childParentMapping.ContainsKey(nodeId))
                    {
                        // Loop thorugh all the tab names
                        foreach (var tabName in tabNames[nodeId])
                        {
                            // Check to see if the parent contains the tab name
                            if (ContainsTabName(childParentMapping[nodeId], tabName, childParentMapping, tabNames))
                            {
                                var row = duplicateTabTable.NewRow();
                                row["nodeId"] = nodeId;
                                row["text"] = tabName;
                                row["nodeObjectType"] = nodeObjectType;
                                row["alias"] = docTypeAlias[nodeId];
                                row["masterContentType"] = childParentMapping[nodeId];
                                duplicateTabTable.Rows.Add(row);
                            }
                        }
                    }
                }

            }


            TabGridView.DataSource = duplicateTabTable;
            TabGridView.DataBind();

            NoResultsLabel.Visible = (duplicateTabTable.Rows.Count == 0);
        }

        /// <summary>
        /// Give a childParentMapping and a list of tabNames (by node), search for a tabName value in tabName list recursively
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="tabName"></param>
        /// <param name="childParentMapping"></param>
        /// <param name="tabNames"></param>
        /// <returns></returns>
        public bool ContainsTabName(int nodeId, string tabName, Dictionary<int, int> childParentMapping, Dictionary<int, List<string>> tabNames)
        {
            // Look for the tab name and return true if found
            if (tabNames.ContainsKey(nodeId))
            {
                if (tabNames[nodeId].Contains(tabName))
                {
                    return true;
                }
            }

            // Recursively check the parent
            if (childParentMapping.ContainsKey(nodeId))
            {
                return ContainsTabName(childParentMapping[nodeId], tabName, childParentMapping, tabNames);
            }

            // If not found, then return false
            return false;
        }

    }
}